home *** CD-ROM | disk | FTP | other *** search
- // ZOOM.CPP
-
- #include <stdlib.h>
- #include <math.h>
- #include <dos.h>
- #include "stdio.h"
- #include "timer.h"
- #include "vx.h"
-
- #define SLOW 0
- #define MSEKDELAY 50
-
- //#define NOTUNE
- //#define NODRAW
-
- #define FRAMES 44 // Number of times the resolution is doubled
- #define EXT 192 // Size of window, in pixels
- #define ROUGHSPLITS 12
- #define FRACX 0
- #define FRACY 0
-
- #if EXT>96
- #define SLOW 0
- #endif
-
- extern timer_C timer;
- extern vx_C vx;
- extern byte *keypressed;
-
- // GLOBALS
-
- word zoomvramptr=0xa000;
- static byte *bitdata[FRAMES-1],*frac1b,*frac2b,*frac3b,*frac1,*frac2,*frac3;
- word datalengths[FRAMES-1];
- word innerlen,innerleft,innertop,innerfac,inneradr,farfac;
- byte startx,starty,nearstartx,nearstarty;
- byte *globalbmp;
-
- // SETZCOLORS
-
- void setzcolors(void)
- {
- for (int teller=1; teller<256; teller++)
- {
- float r=sin(teller*1.2*M_PI/255);
- float g=sin(teller*1.8*M_PI/255);
- float b=sin(teller*2.4*M_PI/255);
-
- r=fabs(r)*63;
- g=fabs(g)*63;
- b=fabs(b)*63;
-
- vx.setrgb(teller,r,g,b);
- }
- }
-
- // ROUGHSPLIT
-
- void roughsplit(byte *from, byte *to,word stripno)
- {
- long from_ptr=(long)from;
- long to_ptr=(long)to;
- to_ptr+=EXT*stripno*(EXT/ROUGHSPLITS);
- from_ptr+=(EXT/4)+(EXT/4)*EXT+(EXT*stripno*(EXT/ROUGHSPLITS)/2);
-
- asm pusha
- asm push ds
-
- asm cld
- asm les di,to_ptr
- asm lds si,from_ptr
-
- asm mov bx,es
- asm mov ch,(EXT/ROUGHSPLITS)/2
- nextline:
- asm mov cl,EXT/2
- nextpixel: // unroll!
- asm lodsb
- asm stosb
- asm stosb
- asm dec cl
- asm jnz nextpixel
- asm add di,EXT
- asm add si,EXT/2
- asm dec ch
- asm jnz nextline
- asm lds si,to_ptr
- asm mov di,si
- asm mov ax,EXT
- asm add di,ax
- asm mov dl,(EXT/ROUGHSPLITS)/2
- twinline:
- #if USE32BIT
- asm mov cx,EXT/4
- asm rep movsd
- #else
- asm mov cx,EXT/2
- asm rep movsw
- asm add si,ax
- asm add di,ax
- #endif
- asm dec dl
- asm jnz twinline
- asm pop ds
- asm popa
-
- }
-
- byte *datas,datamask,lastpopped;
-
- // POPBIT
-
- byte _fastcall popbit(void)
- {
- asm les bx,dword ptr datas
- asm mov al,[es:bx]
- asm and al,datamask
- asm shr datamask,1
- asm jnc ok
- asm mov datamask,128
- asm inc word ptr datas
- ok:
- }
-
- // CTEST
-
- void near _pascal ctest(int x,int y,byte len)
- {
- #ifdef NOTUNE
- return;
- #endif
- static byte p,fac;
- int yy,xx;
- asm les bx,dword ptr datas // es = kontant ptr->datas
- asm mov yy,2
- newx:
- asm mov xx,2
- nextx:
- asm les bx,dword ptr datas // es = kontant ptr->datas
- asm mov al,[es:bx]
- asm and al,datamask
- asm shr datamask,1
- asm jnc ok
- asm mov datamask,128
- asm inc word ptr datas
- ok:
- asm and al,al
- asm jnz doit
- goto staylow;
- doit:
- if (len>2)
- {
- static word nx,ny;
- word len2=len;
- len2>>=1;
- nx=0;
- ny=0;
- if (xx==1)
- nx=len2;
- if (yy==1)
- ny=len2;
- ctest(x+nx,y+ny,len2);
- }
- else
- {
- byte color=0;
- asm les bx,dword ptr datas // es = kontant ptr->datas
- asm mov al,[es:bx]
- asm and al,datamask
- asm shr datamask,1
- asm jnc againok
- asm mov datamask,128
- asm inc word ptr datas
- againok:
- asm and al,al
- asm jz notvip
-
- if (popbit())
- color=1;
- else
- color=-1;
- goto vipdone;
- notvip:
- color=0;
- p=popbit();
- fac=1;
- if (popbit()) color+=fac; fac<<=1;
- if (popbit()) color+=fac; fac<<=1;
- if (popbit()) color+=fac; fac<<=1;
- if (p)
- color+=2;
- else
- {
- color+=247;
- if (color==247)
- {
- fac=1;
- color=0;
- if (popbit()) color+=fac; fac<<=1;
- if (popbit()) color+=fac; fac<<=1;
- if (popbit()) color+=fac; fac<<=1;
- if (popbit()) color+=fac; fac<<=1;
- if (popbit()) color+=fac; fac<<=1;
- if (popbit()) color+=fac; fac<<=1;
- if (popbit()) color+=fac; fac<<=1;
- if (popbit()) color+=fac; fac<<=1;
- }
- }
- vipdone:
- globalbmp[(x+2-xx)*EXT+y+2-yy]+=color;
- }
- staylow:
- asm dec xx
- asm jz xdone
- asm jmp nextx
- xdone:
- asm dec yy
- asm jz ydone
- asm jmp newx
- ydone:
- }
-
- // FINEMASK
-
- void finemask(byte *bits,byte *bmp,word no)
- {
- static long bit_ptr;
- bit_ptr=(long)bits;
- if (!no)
- datas=(byte *)bit_ptr;
- globalbmp=bmp;
- datamask=128;
- ctest((no%6)*(EXT/6),(no/6)*(EXT/6),(EXT/6));
- while (datamask<0x80)
- popbit();
- }
-
-
-
- // DRAWNEAR
-
- void drawnear(word sx,word sy,word height, word width,long bmp_ptr)
- {
- #ifdef NODRAW
- return;
- #endif
- if (!width || !height)
- return;
-
- byte nearstarty_ss=nearstarty;
- word start,startdi;
- byte br0kx=nearstartx;
-
- asm pusha
- asm push ds
-
- asm mov dx,zoomvramptr
- asm mov es,dx
- asm mov dx,sx
- asm mov cx,dx
- asm shr dx,2
- asm mov di,dx
- asm mov dx,sy
- asm shl dx,4
- asm add di,dx
- asm add dx,dx
- asm add dx,dx
- asm add di,dx // di = screenpos
-
- asm mov bh,byte ptr innerfac // bx = innerfac
- asm lds si,bmp_ptr
- asm mov ch,byte ptr height // ch = y-teller
- asm and cl,3
- next_strip:
- asm mov start,si
- asm mov ax,0x0100+MAP_MASK
- asm shl ah,cl
- asm mov dx,SC_INDEX
- asm out dx,ax
-
- asm mov startdi,di
- asm mov dx,79
- asm mov bl,byte ptr width // bl = x-teller, ah = br0k-y
- asm mov al,nearstarty_ss
- next_down: // unroll!
- asm movsb
- asm add di,dx
- asm add ah,bh
- asm adc si,0
- asm dec bl
- asm jnz next_down
- asm mov si,start
- asm add si,EXT
- asm add br0kx,bh
- asm jnc nomoreright
- asm add si,EXT
- nomoreright:
- asm mov di,startdi
- asm inc cl
- asm test cl,4
- asm jz dontadvanceright
- asm inc di
- asm xor cl,cl
- dontadvanceright:
- asm dec ch
- asm jnz next_strip
-
- asm pop ds
- asm popa
- }
-
- // DRAWFAR
-
- void drawfar(word sx,word sy,word height, word width,long bmp_ptr)
- {
- #ifdef NODRAW
- return;
- #endif
- if (!width || !height)
- return;
-
- word start,startdi;
- byte br0kx=startx;
- byte starty_ss=starty;
-
- asm pusha
- asm push ds
-
- asm mov dx,zoomvramptr
- asm mov es,dx
- asm mov dx,sx
- asm mov cx,dx
- asm shr dx,2
- asm mov di,dx
- asm mov dx,sy
- asm shl dx,4
- asm add di,dx
- asm add dx,dx
- asm add dx,dx
- asm add di,dx // di = screenpos
-
- asm mov bh,byte ptr farfac // bx = innerfac
- asm lds si,bmp_ptr
- asm mov ch,byte ptr height // ch = y-teller
- asm and cl,3
- next_strip:
- asm mov start,si
- asm mov ax,0x0100+MAP_MASK
- asm shl ah,cl
- asm mov dx,SC_INDEX
- asm out dx,ax
-
- asm mov startdi,di
- asm mov dx,80
- asm mov al,byte ptr width // al = x-teller, ah = br0k-y
- asm mov ah,starty_ss
- next_down: // unroll!
- asm mov bl,[si]
- asm mov [es:di],bl
- asm add di,dx
- asm add ah,bh
- asm adc si,0
- asm dec al
- asm jnz next_down
- asm mov si,start
- asm add br0kx,bh
- asm jnc nomoreright
- asm add si,EXT
- nomoreright:
- asm mov di,startdi
- asm inc cl
- asm test cl,4
- asm jz dontadvanceright
- asm inc di
- asm xor cl,cl
- dontadvanceright:
- asm dec ch
- asm jnz next_strip
-
- asm pop ds
- asm popa
- return;
- singleline:
- }
-
- // CONV
-
- word conv(int x,int y,int tune)
- {
- float fx,fy;
-
- float nearmov=tune/48.0;
- float mov=nearmov/2;
-
- fx=x-FRACX-EXT/2;
- fy=y-FRACY-EXT/2;
- fx/=EXT/2.0;
- fy/=EXT/2.0;
- float fxx=fx*(EXT/2)*(1-mov)+EXT/2;
- float fyy=fy*(EXT/2)*(1-mov)+EXT/2;
-
- int xxx=fxx;
- int yyy=fyy;
- fxx-=xxx;
- fyy-=yyy;
- startx=255.99*fxx;
- starty=255.99*fyy;
- farfac=255.99*(1-mov);
-
- return yyy+EXT*xxx;
- }
-
- // SETZOOM
-
- void setzoom(int zfac)
- {
- if (!zfac)
- {
- innerleft=FRACX+EXT/4;
- innertop=FRACY+EXT/4;
- innerlen=EXT/2+1;
- innerfac=255;
- return;
- }
- float mov=zfac/48.0;
- float innerlenf=EXT/(2.0-mov);
- innerlen=innerlenf;
- float realinnerleft=FRACX+EXT/2-innerlen/2;
- float realinnertop=FRACY+EXT/2-innerlen/2;
- innertop=realinnertop;
- innerleft=realinnerleft;
- realinnerleft-=innerleft;
- realinnertop-=innertop;
- nearstartx=0;
- nearstarty=0;
- inneradr=innerleft+80*innertop;
- innerfac=255*(2.0-mov);
- innerfac-=256;
- }
-
- // DRAWZOOM
-
- void drawzoom(long frac1,long frac2,int tune1)
- {
- float ftune=(tune1/48.0);
- drawnear(innerleft,innertop,innerlen,innerlen,frac2);
- int tlpluss,trpluss,cupluss,cdpluss;
- tlpluss=conv(0,0,tune1);
- if (tune1>0)
- {
- drawfar(FRACX,FRACY,EXT/2-innerlen/2,EXT,frac1+tlpluss);
- cupluss=conv(innerleft,FRACY,tune1);
- drawfar(innerleft,FRACY,innerlen,EXT/2-innerlen/2,frac1+cupluss);
- trpluss=conv(FRACX+EXT/2+innerlen/2,FRACY,tune1);
- drawfar(FRACX+EXT/2+innerlen/2,FRACY,EXT/2-innerlen/2,EXT,frac1+trpluss);
- cdpluss=conv(innerleft,FRACX+EXT/2+innerlen/2,tune1);
- drawfar(innerleft,FRACX+EXT/2+innerlen/2,innerlen,EXT/2-innerlen/2,
- frac1+cdpluss);
- }
- else
- {
- drawfar(FRACX,FRACY,EXT,EXT,frac1+tlpluss);
- }
- }
-
- // SETUPZOOMPAGE
-
- void setupzoompage(void)
- {
- vx.blockfill(0,30000,0);
- vx.blockfill(30000,65535,0);
- vx.setoffset(0);
- }
-
- // ZOOM
-
- // frac1=closest, center of picture
- // frac2=coming up, closest next time
- // frac3=under construction
-
- void zoom(void)
- {
- frac1b=new byte[EXT*EXT+32];
- frac2b=new byte[EXT*EXT+32];
- frac3b=new byte[EXT*EXT+32];
-
- frac1=(byte *)((long)frac1b+65536l);
- frac2=(byte *)((long)frac2b+65536l);
- frac3=(byte *)((long)frac3b+65536l);
-
- setupzoompage();
-
- for (word bl=0; bl<EXT*EXT; bl++)
- frac1[bl]=frac2[bl]=frac3[bl]=0;
-
- setzcolors();
- FILE *f3=fopen("LIGHTC.006","rb");
- fread(frac1,1,EXT*EXT,f3);
- fclose(f3);
- f3=fopen("LIGHTC.007","rb");
- fread(datalengths,2,FRAMES-1,f3);
- FILE *o05=fopen("LIGHTC.005","rb");
- for (int su=0; su<FRAMES-1; su++)
- {
- word len;
- byte *temp=new byte[(len=datalengths[su])+32];
- fread(temp,1,len,o05);
- bitdata[su]=temp;
- }
- fclose(o05);
- word no=0;
-
- for (int teller=0; teller<EXT; teller++)
- for (int t=0; t<EXT; t++)
- {
- frac1[no++]^=(teller+t);
- }
-
- for (teller=0; teller<EXT; teller++)
- for (int t=0; t<EXT; t++)
- vx.putpixel(teller,t,frac1[t+teller*EXT]);
-
- byte *fixfirst=bitdata[0];
- for (int t=0; t<48; t++)
- {
- if (t<12)
- roughsplit(frac1,frac2,t);
- else
- finemask(fixfirst,frac2,t-12);
- }
-
- for (teller=0; teller<SLOW*EXT; teller++)
- for (int t=0; t<EXT; t++)
- {
- vx.putpixel(teller,t+100,frac1[t+teller*EXT]);
- vx.putpixel(teller+100,t+100,frac2[t+teller*EXT]);
- vx.putpixel(teller+200,t+100,frac3[t+teller*EXT]);
- }
-
- for (int runde=0; runde<FRAMES-1; runde++)
- {
- byte *thisjust=bitdata[runde+1];
- for (int tune=0; tune<48; tune++)
- {
- long stop,start;
- stop=start=timer.readtimer();
- if (tune<12)
- roughsplit(frac2,frac3,tune);
- else
- if (runde<FRAMES)
- finemask(thisjust,frac3,tune-12);
- setzoom(tune);
- drawzoom((long)frac1,(long)frac2,tune);
- vx.setoffset((zoomvramptr-0xa000)*16);
- zoomvramptr+=1200;
- if (zoomvramptr==0xa000+3600)
- zoomvramptr=0xa000;
- for (teller=0; teller<SLOW*EXT; teller++)
- for (int t=0; t<EXT; t++)
- {
- vx.putpixel(teller,t+100,frac1[t+teller*EXT]);
- vx.putpixel(teller+100,t+100,frac2[t+teller*EXT]);
- vx.putpixel(teller+200,t+100,frac3[t+teller*EXT]);
- }
- #ifdef MSEKDELAY
- stop=timer.readtimer();
- for (int p=0; p<3; p++)
- vx.putpixel(tune,239-timer.elapsed(start,stop),32+54*runde);
- vx.putpixel(tune,239,32+43*runde);
- while(timer.elapsed(start,stop)<MSEKDELAY)
- stop=timer.readtimer();
- #endif
- if (keypressed[1])
- goto nomore;
- }
- byte *temp=frac3;
- frac3=frac1;
- frac1=frac2;
- frac2=temp;
- }
-
- nomore:
-
- delete frac1b;
- delete frac2b;
- delete frac3b;
- for (int fr=0; fr<FRAMES-1; fr++)
- {
- byte *temp=bitdata[fr];
- if(temp)
- delete temp;
- }
- }
-
-